package com.util.vmwareops;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class AllVMwareInfoOps {
    // 上次获取所有资源信息的时间，如果10分钟内获取过则不需要重新获取
    private static long lastGetAllResourceInfoTime = -100000000;
    private static final long CHECK_GET_TIME = 600000;
    private static List<VCenterInfo> vCenterInfos = null;

    public synchronized static void updateAllResourceInfo() throws InterruptedException, SQLException {
        // 获取数据库中添加的VCenter信息，用于初始化VC连接池
        List<VCenterInfo> vcs = null;
        vcs = VCenterOps.getAllVCInfo();
        if(vcs.size()<=0) {
            return ;
        }

        // 获取VC连接池
        HashMap<String, VCConnectionPool> vcPool = VCConnectionPoolFactory.getAllVCConnectionPool(vcs);

        // 获取最新的版本号，用于插入新的数据
        String latestVersion = ResourceInfoVersionController.getLatestVersion();

        // 遍历每个VC，更新集群、物理机和虚拟机的数据库信息
        try {
            for(VCenterInfo vc : vcs) {
                VCenterOps.updateVCenterResourceInfo(vc, vcPool.get(vc.getName()), latestVersion);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        // 将新版本号赋给当前版本号
        ResourceInfoVersionController.resetCurrentVersion();

        // 将不等于新版本号的数据删除掉
        deleteOldVersionData(ResourceInfoVersionController.getCurrentVersion());
    }

    public synchronized static void deleteOldVersionData(String currentVesion) throws SQLException, InterruptedException {

        System.out.println("[INFO] Delete old version data, current version: " + currentVesion);
        // 获取DB连接池连接
        DBConnectionPool dbPool = DBConnectionPoolFactory.getDBConnectionPool("vmwareops");
        Connection con = dbPool.getConnection();

        Statement stmt = null;
        stmt = con.createStatement();

        String[] tableName = new String[]{
                "resource_bundle_vsphere_cluster",
                "vsphere_host_network",
                "vsphere_host_datastore",
                "resource_bundle_vsphere_host",
                "resource_bundle_vsphere_vm",
                "resource_bundle_vsphere_network",
                "resource_bundle_vsphere_datastore",
        };
        for(String table : tableName) {
            String sql_command = String.format(
                    "delete from %s where version!=\'%s\'",
                    table,
                    currentVesion
            );
            boolean isSuccess = stmt.execute(sql_command);
        }
        dbPool.close(con);
    }

    // 获取当前数据库中所有的Vmware信息，如果10分钟内获取过，则直接返回上次已经获取的内容
    public synchronized static List<VCenterInfo> getAllResourceInfo() throws InterruptedException {
        long currentTime = System.currentTimeMillis();
        if(currentTime - lastGetAllResourceInfoTime < CHECK_GET_TIME && vCenterInfos != null) {
            return vCenterInfos;
        }

        // 获取VC信息并将其转化为Map形式用于添加关系
        Map<String, VCenterInfo> vCenterInfoMap = new HashMap<String, VCenterInfo>();
        vCenterInfos = VCenterOps.getAllVCInfo();
        for(VCenterInfo vcInfo : vCenterInfos) {
            vCenterInfoMap.put(vcInfo.getId(), vcInfo);
        }

        // 获取当前使用版本
        String versionId = ResourceInfoVersionController.getCurrentVersion();

        // 获取数据库中当前版本的集群、主机、网络、存储和虚拟机信息，因为要创建关联关系，数据库中关联关系使用的是主键，所以建立了主键为key的map
        Map<String, ClusterInfo> clusterInfos = ClusterOps.getClusterInfoByVersionId(versionId, vCenterInfoMap);
        Map<String, HostInfo> hostInfos = HostOps.getHostInfoByVersionId(versionId, clusterInfos);
        Map<String, NetworkInfo> networkInfos = NetworkOps.getNetworkInfoByVersionId(versionId);
        Map<String, DatastoreInfo> datastoreInfos = DatastoreOps.getDatastoreInfoByVersionId(versionId);
        List<VMInfo> vmInfos = VirtualMachineOps.getVMInfoByVersionId(versionId, hostInfos);

        // 获取数据库中当前版本的物理主机与网络、存储的关联关系
        Map<String,List<NetworkInfo>> host_network = HostOps.getHostNetworkByVersionId(versionId, networkInfos);
        Map<String, List<DatastoreInfo>> host_datastore = HostOps.getHostDatastoreByVersionId(versionId, datastoreInfos);

        // 建立VMware资源的关联关系
        for(VMInfo vm : vmInfos) {
            hostInfos.get(vm.getHost().getId()).getVms().add(vm);
        }

        // 建立物理主机与网络和存储的关系
        for(String hostId : host_network.keySet()) {
            hostInfos.get(hostId).setNetworks(host_network.get(hostId));
        }
        for(String hostId : host_datastore.keySet()) {
            hostInfos.get(hostId).setDatastores(host_datastore.get(hostId));
        }

        // 建立集群与物理主机的关系
        for(HostInfo host : hostInfos.values()) {
            clusterInfos.get(host.getCluster().getId()).getHosts().add(host);
        }

        // 建立VC与集群的管理关系
        for(ClusterInfo cluster : clusterInfos.values()) {
            vCenterInfoMap.get(cluster.getVc().getId()).getClusters().add(cluster);
        }

        AllVMwareInfoOps.setLastGetAllResourceInfoTime(System.currentTimeMillis());
        vCenterInfos = new ArrayList<VCenterInfo>(vCenterInfoMap.values());
        return vCenterInfos;
    }
    public static synchronized void setLastGetAllResourceInfoTime(long changeTime) {
        lastGetAllResourceInfoTime = changeTime;
    }
}
